﻿using DG.Tweening;
using UnityEngine;

namespace Sliver.Scene.GameControl
{
    public class CameraController : MonoBehaviour
    {
        public static CameraController Instance { get; private set; }

        public Transform MainCameraCenter;
        public Transform MeeplePlacementCameraCenter;

        public Camera MainCamera;
        public Camera MeeplePlacementCamera;

        protected Transform MainCameraTransform;

        public float CameraMoveSpeed = 8.0f;
        public float CameraSettingsSpeed = 1.0f;
        public float CameraZoomSpeed = 0.5f;

        // public ETCJoystick Joystick;

        protected enum ControllerState
        {
            Idle,
            ClickDown0,
            ClickDown1,
            TwoFingerDown,
            Drag,
            PinchIn,
            PinchOut,
            Twist,
        }

        protected int TouchCount = 0;

        protected ControllerState controllerState = ControllerState.Idle;

        protected bool OnIdleState => controllerState == ControllerState.ClickDown0 ||
                                      controllerState == ControllerState.ClickDown1 ||
                                      controllerState == ControllerState.TwoFingerDown ||
                                      controllerState == ControllerState.Idle;

        protected bool OnOneFingerState => controllerState == ControllerState.ClickDown0 ||
                                           controllerState == ControllerState.ClickDown1 ||
                                           controllerState == ControllerState.Drag;

        protected bool OnTwoFingerState => controllerState == ControllerState.TwoFingerDown ||
                                           controllerState == ControllerState.PinchIn ||
                                           controllerState == ControllerState.PinchOut ||
                                           controllerState == ControllerState.Twist;

        protected void Awake()
        {
            Instance = this;
            MainCameraTransform = MainCamera.transform;
        }

        protected void Start()
        {
        }

        protected void OnDestroy()
        {
        }

        protected void Update()
        {
            if (GameInput.GetMouseButtonDown(0))
            {
                controllerState = ControllerState.ClickDown0;
            }

            if (GameInput.GetMouseButtonDown(1))
            {
                controllerState = ControllerState.ClickDown1;
            }

            // 移动端触控初始化
            if (GameInput.TouchCount == 1)
            {
                controllerState = ControllerState.ClickDown0;
            }
            else if (GameInput.TouchCount == 2)
            {
                controllerState = ControllerState.TwoFingerDown;
            }

            if (GameInput.MouseScrollDelta > 0)
            {
                if (MainCameraTransform.localPosition.sqrMagnitude > 2)
                {
                    MainCameraTransform.Translate(Vector3.forward * CameraZoomSpeed, Space.Self);
                }
            }
            else if (GameInput.MouseScrollDelta < 0)
            {
                MainCameraTransform.Translate(Vector3.back * CameraZoomSpeed, Space.Self);
            }

            if (GameInput.GetKey(KeyCode.S) && UnderBottom)
            {
                if (GameInput.GetKey(KeyCode.A) && UnderLeft)
                {
                    MainCameraCenter.Translate((Vector3.back + Vector3.left) * Time.deltaTime * CameraMoveSpeed * 0.8f,
                        Space.Self);
                }
                else if (GameInput.GetKey(KeyCode.D) && UnderRight)
                {
                    MainCameraCenter.Translate((Vector3.back + Vector3.right) * Time.deltaTime * CameraMoveSpeed * 0.8f,
                        Space.Self);
                }
                else
                {
                    MainCameraCenter.Translate(Vector3.back * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }
            }
            else if (GameInput.GetKey(KeyCode.W) && UnderTop)
            {
                if (GameInput.GetKey(KeyCode.A) && UnderLeft)
                {
                    MainCameraCenter.Translate(
                        (Vector3.forward + Vector3.left) * Time.deltaTime * CameraMoveSpeed * 0.8f,
                        Space.Self);
                }
                else if (GameInput.GetKey(KeyCode.D) && UnderRight)
                {
                    MainCameraCenter.Translate(
                        (Vector3.forward + Vector3.right) * Time.deltaTime * CameraMoveSpeed * 0.8f,
                        Space.Self);
                }
                else
                {
                    MainCameraCenter.Translate(Vector3.forward * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }
            }
            else if (GameInput.GetKey(KeyCode.A) && UnderLeft)
            {
                MainCameraCenter.Translate(Vector3.left * Time.deltaTime * CameraMoveSpeed, Space.Self);
            }
            else if (GameInput.GetKey(KeyCode.D) && UnderRight)
            {
                MainCameraCenter.Translate(Vector3.right * Time.deltaTime * CameraMoveSpeed, Space.Self);
            }
            else if (GameInput.GetKey(KeyCode.Space))
            {
                MainCamera.transform.Translate(Vector3.up * Time.deltaTime * CameraMoveSpeed, Space.World);
            }
            else if(GameInput.GetKey(KeyCode.V))
            {
                MainCamera.transform.Translate(-Vector3.up * Time.deltaTime * CameraMoveSpeed, Space.World);
            }
            else
            {
                Vector2 mouse = Input.mousePosition;

                if (mouse.x < 5 && mouse.x >= 0 && UnderLeft)
                {
                    MainCameraCenter.Translate(Vector3.left * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }

                if (mouse.y < 5 && mouse.y >= 0 && UnderTop)
                {
                    MainCameraCenter.Translate(Vector3.back * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }

                if (mouse.x > (Screen.width - 5) && mouse.x <= Screen.width && UnderRight)
                {
                    MainCameraCenter.Translate(Vector3.right * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }

                if (mouse.y > (Screen.height - 5) && mouse.y <= Screen.height && UnderBottom)
                {
                    MainCameraCenter.Translate(Vector3.forward * Time.deltaTime * CameraMoveSpeed, Space.Self);
                }
            }

            HandleInputCameraRotate();

            // 重置状态
            switch (controllerState)
            {
                case ControllerState.ClickDown0:
                    if (GameInput.GetMouseButtonDown(0)) controllerState = ControllerState.Idle;
                    break;
                case ControllerState.ClickDown1:
                    if (GameInput.GetMouseButtonDown(1)) controllerState = ControllerState.Idle;
                    break;
            }

            MainCameraTransform.LookAt(MainCameraCenter);
        }

        protected Vector2 MobileTouchStartPosition;
        protected Vector3 CameraCenterCachePosition;
        protected Vector3 MobileTouchStartPositionGameTable;

        public const float Offset = 2.5f;

        // protected bool UnderTop => MainCameraCenter.position.z - Offset < GameManager.Instance.GameTable.Top;
        // protected bool UnderBottom => MainCameraCenter.position.z + Offset > GameManager.Instance.GameTable.Bottom;
        // protected bool UnderLeft => MainCameraCenter.position.x + Offset > GameManager.Instance.GameTable.Left;
        // protected bool UnderRight => MainCameraCenter.position.x - Offset < GameManager.Instance.GameTable.Right;

        protected bool UnderTop => true;
        protected bool UnderBottom => true;
        protected bool UnderLeft => true;
        protected bool UnderRight => true;

        private bool _rotating = false;
        // private float _rotateSpeed = 100f;

        protected int Rotation = 0;

        protected void HandleInputCameraRotate()
        {
            if (_rotating) return;

            if (GameInput.GetKey(KeyCode.Z))
            {
                _rotating = true;

                Rotation = (Rotation + 1) % 8;
                MainCameraCenter.DORotate(new Vector3(0, Rotation * 45, 0), 0.25f).onComplete = () =>
                {
                    _rotating = false;
                };
                MeeplePlacementCameraCenter.DORotate(new Vector3(0, Rotation * 45, 0), 0.25f);
            }
            else if (GameInput.GetKey(KeyCode.X))
            {
                _rotating = true;

                Rotation = (Rotation + 7) % 8;
                MainCameraCenter.DORotate(new Vector3(0, Rotation * 45, 0), 0.25f).onComplete = () =>
                {
                    _rotating = false;
                };
                MeeplePlacementCameraCenter.DORotate(new Vector3(0, Rotation * 45, 0), 0.25f);
            }
            else if (GameInput.GetKey(KeyCode.C))
            {
                // 回复原始角度
                // CameraCenter.DORotate(Quaternion.identity.eulerAngles, 0.25f);

                _rotating = true;
                // CameraCenter.Rotate(Vector3.up, Time.deltaTime * _rotateSpeed);

                int angle = (int)(Quaternion.Angle(MainCameraCenter.rotation, Quaternion.identity) + 0.2f);
                angle /= 45;

                MainCameraCenter.DORotate(new Vector3(0, 0, 0), angle * 0.25f).onComplete = () =>
                {
                    Rotation = 0;
                    _rotating = false;
                };
                MeeplePlacementCameraCenter.DORotate(new Vector3(0, 0, 0), angle * 0.25f);
            }

            if (!_rotating)
            {
            }
        }

        protected void OnJoystickMove(Vector2 v)
        {
            float dx = Vector2.Dot(v, Vector2.left);
            float dy = Vector2.Dot(v, Vector2.up);

            if (dx > 0)
            {
                if (!UnderLeft) v = Vector3.Project(v, Vector2.up);
            }
            else
            {
                if (!UnderRight) v = Vector3.Project(v, Vector2.up);
            }

            if (dy > 0)
            {
                if (!UnderTop) v = Vector3.Project(v, Vector2.left);
            }
            else
            {
                if (!UnderBottom) v = Vector3.Project(v, Vector2.left);
            }

            MainCameraCenter.Translate(new Vector3(v.x, 0, v.y) * 0.75f, Space.Self);
        }

        protected const float PinchThreshold = 3f;


        protected float PinchDeltaAccumulate = 0;
        protected static float PinchChangeThreshold = Screen.height / 10f;

        private void OnTwist()
        {
            if (controllerState == ControllerState.TwoFingerDown)
            {
                controllerState = ControllerState.Twist;
            }
        }
    }
}